# TF-IDF & TextRank

# TF-IDF

词频-逆文档频率(Term Frequency-Inverse Document Frequency,TF-IDF)是一种用于资讯检索和文本挖掘的常用加权技术。

TF-IDF是一种统计方法,用以评估一个词对于一个文件集或者一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加(词频增加),但同时会随着它在语料库中出现的频率成反比下降(文档频率下降)

TFIdF=TFIdFTF-IdF = TF * IdF

主要思想:如果某个词或者短语在某一篇文章中出现的词频高,但在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用于分类,可以作为该文章的主题词

import pandas as pd
import math

class TF_IDF:
    
    def __init__(self):
        pass
    
    def compute_tf(self, word_dict, bow):
        tf = {}
        n = len(bow)
        for word, count in word_dict.items():
            tf[word] = count / n
        return tf
    
    def compute_idf(self, word_dict_list):
        """
        计算IDF = log10((N+1)/(Ni+1)),如果每个文档中都存在某个词,则IDF=0
        :param word_dict_list:
        :return: IDF
        """
        idf = {}.fromkeys(word_dict_list[0], 0)
        N = len(word_dict_list)
        for word_dict in word_dict_list:
            for word, count in word_dict.items():
                if count > 0:
                    idf[word] += 1
        for word, ni in idf.items():
           idf[word] = math.log10((N+1)/(ni+1))
        return idf

    def compute_tf_idf(self, tf, idf):
        tf_idfs = {}
        for word, tfval in tf.items():
            tf_idfs[word] = tfval*idf[word]
        return tf_idfs
    
# 有两个文档
doc_a = "The cat sat on my bed"
doc_b = "The dog sat on my knees"

# 对两个文档分词
bow_a = set(doc_a.split(" "))
bow_b = set(doc_b.split(" "))

# 统计每个文档的词典
word_set = bow_a.union(bow_b)
word_dict_a = dict.fromkeys(word_set, 0)
word_dict_b = dict.fromkeys(word_set, 0)
for word in bow_a:
    word_dict_a[word] += 1
for word in bow_b:
    word_dict_b[word] += 1
    
# 计算TF-IDF
tf_idf = TF_IDF()
tf_a = tf_idf.compute_tf(word_dict_a, bow_a)
tf_b = tf_idf.compute_tf(word_dict_b, bow_b)
idf = tf_idf.compute_idf([word_dict_a, word_dict_b])
tf_idf_a = tf_idf.compute_tf_idf(tf_a, idf)
tf_idf_b = tf_idf.compute_tf_idf(tf_b, idf)

print(pd.DataFrame([tf_idf_a, tf_idf_b]))

结果如下:

其中文档1中的关键词是catbed;文档2中的关键词是kneesdog

# TextRank

# PageRank

textrank借用了网页排名pagerank的思想;一个网页连接到其他网页越多,说明重要程度越低,一个网页被链接越多,说明重要程度越高;对于每一个网页间的链接给一个权重,可以用转移矩阵来表征从i节点到j节点的概率(转移概率),因此整个矩阵可以当作权重矩阵。因此,可以设想当用户随机进入一个网站,然后不断通过链接进入下一个网站时,经过n次跳转,稳定之后,用户在每个网页上的概率都趋于稳定值,这就指的是网页的价值;初始可以给每个网页相同权重,比如5个网页

(S)0=(15,15,15,15,15)T(S)^0=(\frac{1}{5}, \frac{1}{5}, \frac{1}{5}, \frac{1}{5}, \frac{1}{5})^T

第n次转移后

(S)n=W(S)(n1)(S)^n=W(S)^{(n-1)}

但是存在一个问题,当某些节点不存在外链时,如果不断迭代,最终每个值都会收敛到0,成为dead ends,为了解决整个问题,引入正则因子,可以当作用户浏览任何一个页面,都有极小的概率跳到任何一个其他页面

(S)n=[W(S)n1,1][d,1d]T(S)^n=[W(S)^{n-1}, 1][d,1-d]^T